package com.warren.test;

/**
 * @version V1.0
 * @Description:
 * @author: warren
 * @date: 2022/7/25$ 9:29$
 */

import com.google.inject.internal.cglib.core.$MethodInfoTransformer;
import com.warren.entity.TmWxmpBanner;

import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Properties;

/**
 * 反射的三种使用方法
 * 1.使用类的class属性来获取该类对应的class Student.class
 * 2.调用对象的getClass方法 student.getClass()
 * 3.使用Class.forName(String className)
 */
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException, IOException {
        //使用类的class属性来获取该类对应的class Student.class
        Class<TmWxmpBanner> tmWxmpBannerClass = TmWxmpBanner.class;
        System.out.println(tmWxmpBannerClass);

        //调用对象的getClass方法
        TmWxmpBanner tmWxmpBanner = new TmWxmpBanner();
        System.out.println(tmWxmpBanner.getClass());

        //使用Class.forName
        Class<TmWxmpBanner> aClass = (Class<TmWxmpBanner>) Class.forName("com.warren.entity.TmWxmpBanner");
        System.out.println(aClass);

        //反射获取构造方法
        Class<?> aClass1 = Class.forName("com.warren.entity.TmWxmpBanner");
        System.out.println("==================================");
        //公共的构造函数
        Constructor<?>[] constructors = aClass1.getConstructors();
        for (Constructor con : constructors) {
            System.out.println(con);
        }
        System.out.println("==================================");
        //拿到所有的构造方法
        Constructor<?>[] declaredConstructors = aClass1.getDeclaredConstructors();
        for (Constructor con : declaredConstructors) {
            System.out.println(con);
        }
        System.out.println("==================================");
//        Class<?> aClass1 = Class.forName("com.warren.entity.TmWxmpBanner");
        //        1.通过类名获得class对象2.通过getConstructor来获得构造对象3.通过newInstance来创建对象
        Constructor<?> constructor = aClass1.getConstructor(Long.class, String.class, String.class);
        Object o = constructor.newInstance(1L, "warren", "warren");
        System.out.println(o);

        //原始方法
        TmWxmpBanner tmWxmpBanner1 = new TmWxmpBanner(1L, "warren", "warren");
        System.out.println(tmWxmpBanner1);
        System.out.println("==================================");
        System.out.println("f反射获取成员名字");
        System.out.println("==================================");
        Class<?> aClass2 = Class.forName("com.warren.entity.TmWxmpBanner");
        Field[] fields = aClass2.getFields();
        for (Field e: fields) {
            System.out.println(e);
        }
        Field[] declaredFields = aClass2.getDeclaredFields();
        for (Field e1:declaredFields) {
            System.out.println(e1);
        }

        System.out.println("==================================");
        TmWxmpBanner tmWxmpBanner2 = new TmWxmpBanner();
        tmWxmpBanner2.setTitle("西安");
        System.out.println(tmWxmpBanner2);
        //获取无参构造创建对象，赋值
        Class<?> aClass3 = Class.forName("com.warren.entity.TmWxmpBanner");
        Object o1 = aClass3.newInstance();
        Field title = aClass3.getField("title");
        //取消检查 暴力反射
        title.setAccessible(true);
        title.set(o1, "西安");
        System.out.println(o1);
        System.out.println("==================================");
        //        反射获取成员方法并使用
        Class<?> aClass4 = Class.forName("com.warren.entity.TmWxmpBanner");
        //本类所有公共的包括继承和超类的方法
//        Method[] methods = aClass4.getMethods();
        System.out.println("==================================");
        //本类所有公有私有的方法，不包含继承的
        Method[] methods = aClass4.getDeclaredMethods();
        for (Method m: methods) {
            System.out.println(m);
        }
        System.out.println("==================================");
        Class<?> aClass5 = Class.forName("com.warren.entity.TmWxmpBanner");
        Object o2 = aClass5.newInstance();
        Method setTitle = aClass5.getDeclaredMethod("test", String.class);
        setTitle.setAccessible(true);
        setTitle.invoke(o2, "warren");
        System.out.println(o2);
        System.out.println("==================================");

//      反射练习:有一个ArrayList<Integer>集合，现在我想在这个集合中添加一个字符串数据，如何实现？
        ArrayList<Integer> array = new ArrayList<>();
        array.add(10);
        array.add(20);
//        array.add("hello");
        Class<? extends ArrayList> aClass6 = array.getClass();
        Method add = aClass6.getMethod("add", Object.class);
        ArrayList o6 = aClass6.newInstance();
        add.invoke(array, "hello");
        System.out.println(array);
        Student student = new Student();
        student.say();
//      练习2：通过配置文件运行类中的方法
        Properties properties = new Properties();
        FileReader fileReader = new FileReader("D:\\nike\\hello-world\\src\\main\\java\\com\\warren\\test\\reflect.txt");
        properties.load(fileReader);
        fileReader.close();
        String className = properties.getProperty("className");
        String method = properties.getProperty("methodName");
        System.out.println(className + " " +method);
        //通过反射来
        Class<?> aClass7 = Class.forName(className);
        Object o3 = aClass7.newInstance();
        System.out.println(o3);
        Method method1 = aClass7.getMethod(method);
        method1.invoke(o3);
    }
}
